package com.foreveross.fetl.queue;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;
import javax.inject.Inject;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Component;

import com.foreveross.fetl.application.IOfficialPlusDayApplication;
import com.foreveross.fetl.application.ISinglePlaneInfoApplication;
import com.foreveross.fetl.core.domain.task.FlightInfoEntity;
import com.foreveross.fetl.core.domain.task.SourceEntity;
import com.foreveross.fetl.core.domain.task.UserCareLineEntity;
import com.foreveross.fetl.queue.util.LogMessageUtils;
import com.foreveross.fetl.util.DateUtils;
import com.foreveross.fetl.vo.OfficialPlusDayVO;
import com.foreveross.fetl.vo.single.AgentVO;
import com.foreveross.fetl.vo.single.SinglePlaneInfoVO;

/**
 * 每天的官网和渠道的航班价差统计
 * @author tss
 * 
 */
@Component
public class FlightOfficialAndChannelPulsStatistics {

	private Logger log = Logger.getLogger("plus");
	

	
	@Resource(name="taskExecutor")
	private  TaskExecutor taskExecutor;
	
	@Inject
	private ISinglePlaneInfoApplication singlePlaneInfoApplication;
	
	@Inject
	private IOfficialPlusDayApplication officialPlusDayApplication;
	
	private int tasksNumber;//任务数 多少条rowkey
	
	private int failuresNumber;//失败数
	
	private int threadsNumber;//线程数目
	
	private int executeNumber;//已执行的任务条数
	
	
	private int insertNumber; //插入条数 
	
	private long startTime;
	
	
	private String taskTime=null;
	
	public void  rollBackNumber(){
		tasksNumber=0;
		failuresNumber=0;
		threadsNumber=0;
		executeNumber=0;
		insertNumber=0;
		startTime = System.currentTimeMillis();
		LogMessageUtils.create("每天官网和渠道航班的差价统计", this.getClass().getSimpleName());
		
	}

	public static void main(String[] args) {
		FlightOfficialAndChannelPulsStatistics job = new FlightOfficialAndChannelPulsStatistics();
		Calendar c = Calendar.getInstance();
		c.add(Calendar.DAY_OF_MONTH, -1);
		job.process(c.getTime());
	}

	/**
	 * 定时任务调用入口
	 */

	public void execute() {
		rollBackNumber();
		long start = System.currentTimeMillis();
		log.info("Official And Channel Puls %3/6% Statistics start："
				+ DateUtils.format(new Date(), "yyyy-MM-dd hh:mm:ss.SSS"));
		try{
			Calendar cal = Calendar.getInstance();
			cal.add(Calendar.DAY_OF_MONTH, 3);
			//统计未来第3天，第7天，第15天
			process(cal.getTime());
			
			cal = Calendar.getInstance();
			cal.add(Calendar.DAY_OF_MONTH, 7);
			//统计未来第3天，第7天，第15天
			process(cal.getTime());
			
			cal = Calendar.getInstance();
			cal.add(Calendar.DAY_OF_MONTH, 15);
			//统计未来第3天，第7天，第15天
			process(cal.getTime());
		}finally{
			log.info("Official And Channel Puls %3/6% Statistics end："
					+ DateUtils.format(new Date(), "yyyy-MM-dd hh:mm:ss.SSS") + " spend time:"+(System.currentTimeMillis() - start));
		}
	}
	/**
	 * 统计方法：将官网上的所有航班取出，将官网最新与渠道最新价作对比
	 * 
	 * @param date
	 */
	//@Transactional
	public void process(final Date date) {
		
		log.info("Puls %3/6% Statistics start："+ DateUtils.format(new Date(), "yyyy-MM-dd hh:mm:ss.SSS"));
	//	final FlightInfoEntity fe = new FlightInfoEntity();
		SourceEntity source = new SourceEntity();
		Collection<SourceEntity> channels = source
				.findSourceEntityByType(SourceEntity.TYPE_CHNNAEL);
		Collection<SourceEntity> homes = source
				.findSourceEntityByType(SourceEntity.TYPE_HOME);
//		final TaskTemplateEntity task = new TaskTemplateEntity();
//		final List<TaskTemplateEntity> lines = task
//				.findAllDistinctLine();
		UserCareLineEntity userCareLineEntity =new UserCareLineEntity();
		final List<UserCareLineEntity> lines =userCareLineEntity.findUserCareLines();
		for (final SourceEntity home : homes) {
			for (final SourceEntity channel : channels) {
				for (UserCareLineEntity line : lines) {
					threadsNumber++;
				}
			}
		}
		
		for (final SourceEntity home : homes) {
			for (final SourceEntity channel : channels) {
				taskExecutor.execute(new Runnable() {
					@Override
					public void run() {
						log.info(String.format("Puls per 3/ per 6 Statistics home=%s channel=%s", home.getCarrierKey(), channel.getCarrierKey()));
						for (UserCareLineEntity line : lines) {
							compareOfficalAndChannelPrice(date, home,
									channel, line);
						}
					}
				});

			}
		}
		log.info("Puls per 3/per 6  Statistics end："+ DateUtils.format(new Date(), "yyyy-MM-dd hh:mm:ss.SSS"));
	}
	/**
	 * 从已知的航空公司航班集合中取出某条航线的航班
	 * @param allFlights
	 * @param fromCode
	 * @param toCode
	 * @return
	 */
	private List<FlightInfoEntity> getFlightNoByLine(List<FlightInfoEntity> allFlights,
			String fromCode, String toCode){
		List<FlightInfoEntity> tempFlights = new ArrayList<FlightInfoEntity>();
		if(allFlights != null && StringUtils.isNotBlank(fromCode) && StringUtils.isNotBlank(toCode)){
			for(FlightInfoEntity e : allFlights){
				if(fromCode.equalsIgnoreCase(e.getFromCity())
						&& toCode.equalsIgnoreCase(e.getToCity())){
					tempFlights.add(e);
				}
			}
		}
		return tempFlights;
	}
	/**
	 * 比较官网和渠道的价格
	 * @param fe
	 * @param home
	 * @param channel
	 * @param line
	 */
	private void compareOfficalAndChannelPrice(Date date,
			SourceEntity home, SourceEntity channel, UserCareLineEntity line) {
		String currentDate = DateUtils.format(new Date(), "yyyyMMdd");
		//Collection<FlightInfoEntity> flights;
	//	flights = this.getFlightNoByLine(allFlights, line.getFromCity(), line.getToCity());
		int threshold03 = 0;
		int threshold06 = 0;
		List<String> agentNames = new ArrayList<String>();
		
		List<SinglePlaneInfoVO> listPlaneInfo=singlePlaneInfoApplication.findPlaneInfoProperty(home.getHbaseKey(),null, line.getDepartCityCode(), line.getArrivalCityCode(), DateUtils.format(date, "yyyy-MM-dd"), null,null);
		List<SinglePlaneInfoVO> channelPlaneInfo=singlePlaneInfoApplication.findPlaneInfoProperty(channel.getHbaseKey(),home.getCarrierKey(), line.getDepartCityCode(), line.getArrivalCityCode(), DateUtils.format(date, "yyyy-MM-dd"), null,null);
		for (SinglePlaneInfoVO planeInfo : listPlaneInfo) {
				tasksNumber++;
				try {
					if(!DateUtils.format(null==planeInfo.getGrabDate()? planeInfo.getCreateTime():planeInfo.getGrabDate(), "yyyyMMdd").equals(currentDate)){
						continue;//查询出的记录不是指定要处理的这一天的，则过滤掉
					}
					Double homeLowerPrice =planeInfo.getTotalLowestPrice();
					SinglePlaneInfoVO SinglePlaneInfo =this.getSinglePlaneInfo(channelPlaneInfo,planeInfo.getFlightNo(),planeInfo.getFlightDate());
					if(null==SinglePlaneInfo){
						continue;
					}
					Set<AgentVO> agents=SinglePlaneInfo.getAgents();
					if(null==agents || agents.isEmpty()){//没有代理商的计算航班数
						Double channelLowerPrice = 0d;
						channelLowerPrice = SinglePlaneInfo.getTotalLowestPrice();
						if (channelLowerPrice<homeLowerPrice*0.97) {
							threshold03 = threshold03 + 1;
						}
						if (channelLowerPrice<homeLowerPrice*0.94) {
							threshold06 = threshold06 + 1;
						}
					}else{ //有代理商的
						//过滤重复的代理商名称
						for (AgentVO vo : agents) {
							Double channelLowerPrice = 0d;
							if(vo.getPrice()>0){
								channelLowerPrice=vo.getPrice();
								//根据代理商名称过滤重复的代理商
								if(agentNames.contains(vo.getName()))
									continue;
								agentNames.add(vo.getName());
								if (channelLowerPrice<homeLowerPrice*0.97) {
									threshold03 = threshold03 + 1;
								}
								if (channelLowerPrice<homeLowerPrice*0.94) {
									threshold06 = threshold06 + 1;
								}
							}
						}
					}				
				} catch (Exception e) {
					failuresNumber++;
					e.printStackTrace();
					continue;
				}
		}
		
		if (threshold03 > 0 || threshold06 > 0) {
			log.info("home ="+home.getCarrierKey()+" channel ="+channel.getCarrierKey()+" insert db!");
		/*	saveResultToHBase(line, home, channel, date ,threshold03,
					threshold06);*/
			saveResultToMysql(line, home, channel, date ,threshold03,
					threshold06);
		}
		executeNumber++;
		if(executeNumber==threadsNumber){
			LogMessageUtils.build("每天官网和渠道航班的差价统计", this.getClass().getSimpleName(), 2, null, 
					failuresNumber, tasksNumber, insertNumber, taskTime, startTime);
		}
	}
	
	private SinglePlaneInfoVO getSinglePlaneInfo(
			List<SinglePlaneInfoVO> channelPlaneInfo, String flightNo,
			String flightDate) {
		SinglePlaneInfoVO planInfo=null;
		if(null!=channelPlaneInfo && channelPlaneInfo.size()>0){
			for(SinglePlaneInfoVO vo :channelPlaneInfo){
				if(flightNo.equals(vo.getFlightNo()) && flightDate.equals(vo.getFlightDate())){
					planInfo=vo;
					break;
				}
			}
		}
		return planInfo;
	}

	/**
	 * 将结果保存到mysql中
	 * @param line
	 * @param home
	 * @param channel
	 * @param date
	 * @param threshold03
	 * @param threshold06
	 */
	private void saveResultToMysql(UserCareLineEntity line, SourceEntity home,
			SourceEntity channel,Date date, int threshold03, int threshold06){
		OfficialPlusDayVO vo =new OfficialPlusDayVO();
		vo.setChannel(channel.getHbaseKey());
		vo.setCreateTime(new Date());
		vo.setFromCity(line.getDepartCityCode());
		vo.setFromCityName(line.getDepartcity());
		vo.setToCity(line.getArrivalCityCode());
		vo.setToCityName(line.getArrivalcity());
		vo.setHbaseKey(home.getHbaseKey());
		vo.setReportDate(DateUtils.parse(DateUtils.format(date, "yyyyMMdd"), "yyyyMMdd"));
		vo.setThreshold03(threshold03);
		vo.setThreshold06(threshold06);
		List<OfficialPlusDayVO> oldList=officialPlusDayApplication.findByCondition(vo.getReportDate(), vo.getFromCity(), vo.getToCity(), vo.getChannel(), vo.getHbaseKey());
		if(null!=oldList && oldList.size()>0){
			vo.setId(oldList.get(0).getId());
		}
		officialPlusDayApplication.save(vo);
		insertNumber++;
		
	}
	/**
	 * 将统计结果保存到HBase中
	 * 
	 * @param fe
	 * @param home
	 * @param channel
	 * @param threshold03
	 * @param threshold06
	 */
//	private void saveResultToHBase(TaskTemplateEntity line, SourceEntity home,
//			SourceEntity channel,Date date, long threshold03, long threshold06) {
//		// 将统计结果保存到hbase中
//		StringBuffer rowkeySB = new StringBuffer();
//		rowkeySB.append(DateUtils.format(date, "yyyyMMdd"));
//		rowkeySB.append(home.getHbaseKey());// 官网
//		rowkeySB.append(channel.getHbaseKey());// 渠道
//		rowkeySB.append(line.getFromCity());
//		rowkeySB.append(line.getToCity());
//		Put put = new Put(rowkeySB.toString().getBytes());
//		put.add("content".getBytes(), "threshold03".getBytes(),
//				(threshold03 + "").getBytes());
//		put.add("content".getBytes(), "threshold06".getBytes(),
//				(threshold06 + "").getBytes());
//		try {
//			
//			HBaseHelper.addRecord(
//					HBaseTable.TABLE_FLIGHT_OFFICIAL_CHANNEL_PLUS_DAY, put);// 保存统计结果
//			insertNumber++;
//			if (log.isDebugEnabled()) {
//				log.debug("TABLE_FLIGHT_OFFICIAL_CHANNEL_PLUS_DAY  rowkey["
//						+ rowkeySB.toString() + "]");
//			}
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//	}
//	
	

}
